import axios from 'axios'
import type { AxiosRequestConfig, AxiosInstance } from 'axios'

/**
 * Http请求类
 * 封装axios实例和拦截器配置
 */
class HttpRequest {
  // axios实例
  private axiosInstance: AxiosInstance
  /**
   * 构造函数
   * @param config - axios配置项
   */
  constructor(config?: AxiosRequestConfig) {
    this.axiosInstance = axios.create({
      baseURL: import.meta.env.VITE_APP_BASE_API,
      timeout: 50000,
      headers: { 'Content-Type': 'application/json;charset=UTF-8' },
      ...config
    })
    this.setupInterceptors()
  }

  /**
   * 设置请求和响应拦截器
   */
  private setupInterceptors() {
    // 请求拦截器
    this.axiosInstance.interceptors.request.use(
      config => {
        // Token相关业务
        return config
      },
      error => {
        return Promise.reject(error)
      }
    )

    // 响应拦截器
    this.axiosInstance.interceptors.response.use(
      response => {
        // 获取响应数据
        const res = response.data as ResponseData
        // 判断业务状态码
        if (res.code !== 200) {
          // 业务错误处理
          return Promise.reject(new Error(res.message))
        }
        // 返回业务数据
        return res.data
      },
      error => {
        // HTTP错误处理
        return Promise.reject(error)
      }
    )
  }

  /**
   * 通用请求方法
   * @param config - 请求配置
   * @param options - 请求选项
   * @returns Promise
   */
  request<T = any>(config: AxiosRequestConfig, options: RequestOptions = {}): Promise<T> {
    const { isReturnResponse = false } = options
    return new Promise((resolve, reject) => {
      this.axiosInstance
        .request(config)
        .then(res => {
          // 如果需要返回完整响应
          if (isReturnResponse) {
            resolve(res as T)
          } else {
            resolve(res.data as T)
          }
        })
        .catch(error => {
          reject(error)
        })
    })
  }

  /**
   * GET请求
   * @param url - 请求地址
   * @param params - 请求参数
   * @param options - 请求选项
   * @returns Promise
   */
  get<T = any>(url: string, params?: any, options?: RequestOptions): Promise<T> {
    return this.request({ url, method: 'GET', params }, options)
  }
  /**
   * POST请求
   * @param url - 请求地址
   * @param data - 请求数据
   * @param options - 请求选项
   * @returns Promise
   */
  post<T = any>(url: string, data?: any, options?: RequestOptions): Promise<T> {
    return this.request({ url, method: 'POST', data }, options)
  }

  /**
   * PUT请求
   * @param url - 请求地址
   * @param data - 请求数据
   * @param options - 请求选项
   * @returns Promise
   */
  put<T = any>(url: string, data?: any, options?: RequestOptions): Promise<T> {
    return this.request({ url, method: 'PUT', data }, options)
  }

  /**
   * DELETE请求
   * @param url - 请求地址
   * @param data - 请求数据
   * @param options - 请求选项
   * @returns Promise
   */
  delete<T = any>(url: string, data?: any, options?: RequestOptions): Promise<T> {
    return this.request({ url, method: 'DELETE', data }, options)
  }
}

export const http = new HttpRequest()
